package reflect;

import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * java的反射机制
 * 反射是java的动态机制，允许我们在程序运行期间确定实例化对象操作，以及方法的调用和属性
 * 的操作等。
 * 反射机制提高了代码的灵活度，同时也带来了更多的开销和较慢的运行效率。
 * 因此反射机制不能过度依赖。
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
            反射第一步:获取要操作的类的类对象
            类对象:Class类
            JVM（java虚拟机）每当加载一个类时(读取要操作的类的字节码文件)，就会实例化
            一个Class的实例来表示刚加载的这个类。在JVM内部每个被加载的类都有且只有一个
            Class的实例与之对应。通过这个Class实例我们可以在程序运行期间了解其表示的
            类的一切信息(类名，有哪些方法，那些属性，那些构造器等)并在运行期间进行操作

            获取类对象的方式有三种:
            1:类名.class
              Class cls = String.class;
              Class cls = int.class;(基本类型只有这一种方式获取类对象)

            2:Class.forName(String className)
              参数为要操作的类的完全限定名:包名.类名
              Class cls = Class.forName("java.lang.String");

            3:ClassLoader类加载形式获取类对象
         */
        //获取String的类对象，并通过它了解String的相关信息
//        Class cls = String.class;

//        Class cls = Class.forName("java.lang.String");
        /*
            java.lang.String
            java.util.ArrayList
            java.io.FileInputStream
            java.util.HashMap
            reflect.Person
         */
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个类名:");
        String className = scanner.nextLine();
        Class cls = Class.forName(className);

        String name = cls.getName();//获取类名(完全限定名)
        System.out.println(name);
        name = cls.getSimpleName();//仅获取类名
        System.out.println(name);
        /*
            通过类对象获取其表示的类的所有公开方法
            Method类:方法对象
            该类的每一个实例用于表示某个类中的某个方法。
         */
        Method[] methods = cls.getMethods();
        for(Method method : methods){
            System.out.println(method.getName());
        }
    }
}
